package cc.rengu.redp.bizimpl.utils;

import cc.rengu.redp.bizimpl.constant.UpmpConstant;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpRole;
import cc.rengu.redp.bizimpl.upmp.domain.UpmpUserInfo;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpCacheService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpRoleService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpUserInfoService;
import cc.rengu.redp.bizimpl.upmp.service.impl.UpmpCacheServiceImpl;
import cc.rengu.redp.bizimpl.upmp.service.impl.UpmpRoleServiceImpl;
import cc.rengu.redp.bizimpl.upmp.service.impl.UpmpUserInfoServiceImpl;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.base.authentication.UpmpJWTUtil;
import cc.rengu.redp.common.function.CacheSelector;
import cc.rengu.redp.base.service.CacheService;
import cc.rengu.redp.common.utils.SpringContextUtil;
import cc.rengu.redp.system.domain.User;
import cc.rengu.redp.system.service.UserService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * 系统工具类
 */
@Slf4j
public class RedpUpmpUtil {

    /**
     * 缓存查询模板
     *
     * @param cacheSelector    查询缓存的方法
     * @param databaseSelector 数据库查询方法
     * @return T
     */
    public static <T> T selectCacheByTemplate(CacheSelector<T> cacheSelector, Supplier<T> databaseSelector) {
        try {
            log.debug("query data from redis ······");
            // 先查 Redis缓存
            T t = cacheSelector.select();
            if (t == null) {
                // 没有记录再查询数据库
                return databaseSelector.get();
            } else {
                return t;
            }
        } catch (Exception e) {
            // 缓存查询出错，则去数据库查询
            log.error("redis error：", e);
            log.debug("query data from database ······");
            return databaseSelector.get();
        }
    }

    /**
     * 获取当前操作用户
     *
     * @return 用户信息
     */
    public static UpmpUserInfoVO getCurrentUser(String defaultInstId) {
        String token = (String) SecurityUtils.getSubject().getPrincipal();
        String upmpUserId = UpmpJWTUtil.getUpmpUserId(token);//获取用户表ID
        IUpmpUserInfoService userService = SpringContextUtil.getBean(UpmpUserInfoServiceImpl.class);
        IUpmpCacheService cacheService = SpringContextUtil.getBean(UpmpCacheServiceImpl.class);

        UpmpUserInfoVO userVo = selectCacheByTemplate(() -> cacheService.getUser(upmpUserId), () -> userService.findVOById(upmpUserId));
        List<UpmpRole> userRoles = Lists.newArrayList();

        IUpmpRoleService roleService = SpringContextUtil.getBean(UpmpRoleServiceImpl.class);
        userRoles = selectCacheByTemplate(() -> cacheService.getRoles(upmpUserId), () -> roleService.findUserRole(upmpUserId));
        // 判断是否运营中心管理员标志
        if(userRoles.stream().anyMatch(role-> UpmpConstant.SYS_ROLE_SUPER_USER_ROLE_PARAM.equals(role.getRoleCode())) &&
                defaultInstId.equals(userVo.getInstId())){
            userVo.setAdmin(true);
        }
        if(!ObjectUtils.isEmpty(userRoles)){

        }
        userVo.setUserRoles(userRoles);
        return userVo;
    }

    /**
     * 驼峰转下划线
     *
     * @param value 待转换值
     * @return 结果
     */
    public static String camelToUnderscore(String value) {
        if (StringUtils.isBlank(value)) {
            return value;
        }
        String[] arr = StringUtils.splitByCharacterTypeCamelCase(value);
        if (arr.length == 0) {
            return value;
        }
        StringBuilder result = new StringBuilder();
        IntStream.range(0, arr.length).forEach(i -> {
            if (i != arr.length - 1) {
                result.append(arr[i]).append(StringPool.UNDERSCORE);
            } else {
                result.append(arr[i]);
            }
        });
        return StringUtils.lowerCase(result.toString());
    }



}
